﻿#include "cloudshape.h"
#include <cmath>

void drawCloud(QPainter& painter, const QList<QPoint>& points) {
	if (points.size() < 2) return; // 至少需要两个点来绘制半圆  

	QPainterPath path;
	for (int i = 0; i < points.size() - 1; ++i) {
		const QPoint& p1 = points[i];
		const QPoint& p2 = points[i + 1];

		// 计算线段的中点  
		QPoint midPoint((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);

		// 计算线段的长度  
		qreal lineLength = std::sqrt(std::pow(p2.x() - p1.x(), 2) + std::pow(p2.y() - p1.y(), 2));

		// 半径为线段长度的一半  
		qreal radius = lineLength / 2;

		// 计算线段的角度  
		qreal angle = 0;
		if (p1.x() != p2.x()) {
			// 计算斜率  
			qreal slope = static_cast<qreal>(p2.y() - p1.y()) / (p2.x() - p1.x());
			// 计算角度  
			angle = std::atan(slope) * 180 / M_PI;
		}
		else {
			// 垂直线段，角度为90度或-90度  
			angle = (p2.y() > p1.y()) ? 90 : -90;
		}

		// 根据斜率确定起始角度  
		qreal startAngle;
		if (p1.x() < p2.x()) {
			startAngle = 90 - angle;
		}
		else if (p1.x() > p2.x()) {
			startAngle = 90 + angle;
		}
		else {
			// 如果x坐标相同，但y坐标不同，则根据y坐标的相对位置确定起始角度  
			startAngle = (p1.y() < p2.y()) ? 180 : 0;
		}

		// 如果起始角度是负数，需要将其转换为正数，因为QPainterPath的arcTo方法期望正数  
		if (startAngle < 0) {
			startAngle += 360;
		}

		// 绘制半圆  
		path.moveTo(p1); // 移动到当前点的位置  
		path.arcTo(midPoint.x() - radius, midPoint.y() - radius, 2 * radius, 2 * radius, startAngle, 180);
		path.lineTo(p2); // 连接到下一个点，确保路径连续  
	}

	// 绘制路径  
	painter.drawPath(path);
}

CloudShape::CloudShape(QWidget* parent)
	: Shape(parent)
{
	shape_brush = QBrush(QColor(255, 255, 255));
}

void CloudShape::paintPixmap(QPainter& painter)
{
	painter.setPen(shape_pen);
	painter.setBrush(shape_brush);
	QPoint p1(start_point.x() + shape_width * 1 / 8, start_point.y() + shape_height * 5 / 16);
	QPoint p2(start_point.x() + shape_width * 5 /  16, start_point.y() + shape_height * 1 / 8);
	QPoint p3(start_point.x() + shape_width * 11 / 16, start_point.y() + shape_height * 1 / 8);
	QPoint p4(start_point.x() + shape_width * 7 / 8, start_point.y() + shape_height * 5 / 16);
	QPoint p5(start_point.x() + shape_width * 7 / 8, start_point.y() + shape_height * 11 / 16);
	QPoint p6(start_point.x() + shape_width * 11 / 16, start_point.y() + shape_height * 7 / 8);
	QPoint p7(start_point.x() + shape_width * 5 / 16, start_point.y() + shape_height * 7 / 8);
	QPoint p8(start_point.x() + shape_width * 1 / 8, start_point.y() + shape_height * 11 / 16);
	QPainterPath path;
	path.moveTo(p1);
	path.cubicTo(QPoint((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2 - shape_height * 1 / 8), QPoint((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2 - shape_height * 1 / 8), p2);
	path.cubicTo(QPoint((p2.x() + p3.x()) / 2, (p2.y() + p3.y()) / 2 - shape_height * 1 / 8), QPoint((p2.x() + p3.x()) / 2, (p2.y() + p3.y()) / 2 - shape_height * 1 / 8), p3);
	path.cubicTo(QPoint((p3.x() + p4.x()) / 2, (p3.y() + p4.y()) / 2 - shape_height * 1 / 8), QPoint((p3.x() + p4.x()) / 2, (p3.y() + p4.y()) / 2 - shape_height * 1 / 8), p4);
	path.cubicTo(QPoint((p4.x() + p5.x()) / 2 + shape_width * 1 / 8, (p4.y() + p5.y()) / 2), QPoint((p4.x() + p5.x()) / 2 + shape_width * 1 / 8, (p4.y() + p5.y()) / 2), p5);
	path.cubicTo(QPoint((p5.x() + p6.x()) / 2, (p5.y() + p6.y()) / 2 + shape_height * 1 / 8), QPoint((p5.x() + p6.x()) / 2, (p5.y() + p6.y()) / 2 + shape_height * 1 / 8), p6);
	path.cubicTo(QPoint((p6.x() + p7.x()) / 2, (p6.y() + p7.y()) / 2 + shape_height * 1 / 8), QPoint((p6.x() + p7.x()) / 2, (p6.y() + p7.y()) / 2 + shape_height * 1 / 8), p7);
	path.cubicTo(QPoint((p7.x() + p8.x()) / 2, (p7.y() + p8.y()) / 2 + shape_height * 1 / 8), QPoint((p7.x() + p8.x()) / 2, (p7.y() + p8.y()) / 2 + shape_height * 1 / 8), p8);
	path.cubicTo(QPoint((p8.x() + p1.x()) / 2 - shape_width * 1 / 8, (p8.y() + p1.y()) / 2), QPoint((p8.x() + p1.x()) / 2 - shape_width * 1 / 8, (p8.y() + p1.y()) / 2), p1);
	path.closeSubpath();
	painter.drawPath(path);
	//painter.drawLine(p1, p2);
	//painter.drawLine(p2, p3);
	//painter.drawLine(p3, p4);
	//painter.drawLine(p4, p5);
	//painter.drawLine(p5, p6);
	//painter.drawLine(p6, p7);
	//painter.drawLine(p7, p8);
	//painter.drawLine(p8, p1);
	//painter.drawLine(p1, p2);
}

void CloudShape::paintCircle(QPainter& painter)
{
	//默认蓝色外圈
	painter.setPen(QPen(QColor(6, 123, 239)));
	//默认白色内圈
	painter.setBrush(QBrush(QColor(255, 255, 255)));
	//中上
	painter.drawEllipse(QRect(start_point.x() + shape_width / 2 - circle_radius, start_point.y() - circle_radius, circle_radius * 2, circle_radius * 2));
	//左中
	painter.drawEllipse(QRect(start_point.x() - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2));
	//右中
	painter.drawEllipse(QRect(start_point.x() + shape_width - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2));
	//中下
	painter.drawEllipse(QRect(start_point.x() + shape_width / 2 - circle_radius, start_point.y() + shape_height - circle_radius, circle_radius * 2, circle_radius * 2));
}

bool CloudShape::nodesDetect(const QPoint& point)
{
	//包含四个结点，中上，左中，右中，中下，为了避免进行包含求根号的距离计算，我们将点击区域的圆看成一个正方形
	QRect rect_mt(start_point.x() + shape_width / 2 - circle_radius, start_point.y() - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_lm(start_point.x() - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_rm(start_point.x() + shape_width - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_mb(start_point.x() + shape_width / 2 - circle_radius, start_point.y() + shape_height - circle_radius, circle_radius * 2, circle_radius * 2);
	if (rect_mt.contains(point) || rect_lm.contains(point) || rect_rm.contains(point) || rect_mb.contains(point))
		return true;
	return false;
}

bool CloudShape::clickDetect(const QPoint& point)
{
	QRect rect(start_point.x(), start_point.y(), shape_width, shape_height);
	return rect.contains(point);
}

void CloudShape::setNodeIndex(const QPoint& point)
{
	//中上-1，左中-2，右中-3，中下-4
	QRect rect_mt(start_point.x() + shape_width / 2 - circle_radius, start_point.y() - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_lm(start_point.x() - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_rm(start_point.x() + shape_width - circle_radius, start_point.y() + shape_height / 2 - circle_radius, circle_radius * 2, circle_radius * 2);
	QRect rect_mb(start_point.x() + shape_width / 2 - circle_radius, start_point.y() + shape_height - circle_radius, circle_radius * 2, circle_radius * 2);
	if (rect_mt.contains(point))
	{
		nodes_index = 1;
		return;
	}
	if (rect_lm.contains(point))
	{
		nodes_index = 2;
		return;
	}
	if (rect_rm.contains(point))
	{
		nodes_index = 3;
		return;
	}
	if (rect_mb.contains(point))
	{
		nodes_index = 4;
		return;
	}
}

void CloudShape::getNodePoint(QPoint& point, int index) const
{
	if (index == 1)
	{
		point.setX(start_point.x() + shape_width / 2);
		point.setY(start_point.y());
	}
	if (index == 2)
	{
		point.setX(start_point.x());
		point.setY(start_point.y() + shape_height / 2);
	}
	if (index == 3)
	{
		point.setX(start_point.x() + shape_width);
		point.setY(start_point.y() + shape_height / 2);
	}
	if (index == 4)
	{
		point.setX(start_point.x() + shape_width / 2);
		point.setY(start_point.y() + shape_height);
	}
}

ShapeType CloudShape::getType() const
{
	return ShapeType::Cloud;
}

double CloudShape::getRate()
{
	return 1.5;
}
